{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import Image"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Labeling: Fixed Horizon\n",
    "\n",
    "![image_example](img/fixed_horizon_labels_example.png)\n",
    "_*Fig. 1:*_ Distribution of labels for standardized returns on closing prices of SPY in the time period from Jan 2008 to July 2016 using a 20 day rolling window for the standard deviation.\n",
    "\n",
    "\n",
    "## Abstract\n",
    "\n",
    "Fixed Horizon is a classification labelling technique in which time-indexed data is labeled according to whether it exceeds, falls in between, or is less than a threshold. This method is most commonly used with time bars, but also be applied to any time-indexed data such as dollar or volume bars. The subsequent labelled data can then be used as training and test data for ML algorithms.\n",
    "\n",
    "The following paper outlines the technique in greater depth, and is followed closely in this notebook tutorial: [\"Classification-based Financial Markets Prediction using Deep Neural Networks\"](https://arxiv.org/abs/1603.08604) by _Dixon et al._ (2016). \n",
    "\n",
    "\n",
    "## How it works\n",
    "\n",
    "Fixed time horizon is a common method used in labeling financial data, usually applied on time bars. The forward rate of return relative\n",
    "to $t_0$ over time horizon $h$ is calculated as follows:\n",
    "\n",
    "\n",
    "   $$r_{t0,t1} = \\frac{p_{t1}}{p_{t0}} - 1$$\n",
    "\n",
    "Where $t_1 = t_0 + h$ is the time bar index after a fixed horizon of $h$ ticks have passed, and $p_{t0}, p_{t1}$\n",
    "are prices at times $t_0, t_1$. This method assigns a label based on comparison of rate of return to a threshold $\\tau$\n",
    "\\[Lopez de Prado 2018\\]:\n",
    "\n",
    "$$\n",
    "     \\begin{equation}\n",
    "     \\begin{split}\n",
    "       L_{t0, t1} = \\begin{cases}\n",
    "       -1 &\\ \\text{if} \\ \\ r_{t0, t1} < -\\tau\\\\\n",
    "       0 &\\ \\text{if} \\ \\ -\\tau \\leq r_{t0, t1} \\leq \\tau\\\\\n",
    "       1 &\\ \\text{if} \\ \\ r_{t0, t1} > \\tau\n",
    "       \\end{cases}\n",
    "     \\end{split}\n",
    "     \\end{equation}\n",
    "$$\n",
    "\n",
    "Though time bars are the most common format for financial data, there can be potential problems with over reliance on time bars. First,\n",
    "time bars exhibit high seasonality, as trading behavior may be quite different at the open or close versus midday; thus it will not be\n",
    "informative to apply the same thershold on non-uniform distribution. Solutions include applying the fixed horizon method to tick or\n",
    "volume bars instead of time bars, using data sampled at the same time every day (e.g. closing prices) or inputting a dynamic threshold\n",
    "as a pd.Series corresponding to the times in the dataset. Another solution is to apply the labels to data based on standardized returns \\[Lopez de Prado, 2020: p.66\\]. In this case, the data is scaled by mean and standard deviation based on a given rolling window before labels are applied.\n",
    "\n",
    "---\n",
    "## Examples of use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import yfinance as yf\n",
    "\n",
    "from mlfinlab.labeling import fixed_time_horizon\n",
    "\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Date\n",
       "2010-01-04    24.23\n",
       "2010-01-05    24.23\n",
       "2010-01-06    24.09\n",
       "2010-01-07    23.84\n",
       "2010-01-08    24.00\n",
       "Name: Close, dtype: float64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Load price data\n",
    "msft = yf.Ticker('MSFT')\n",
    "msft_df = msft.history(start='2010-1-1', end ='2020-5-18')\n",
    "\n",
    "# Subset closing prices\n",
    "close = msft_df['Close']\n",
    "close.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Labeling Financial Time Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       " 0.0    1596\n",
       " 1.0     560\n",
       "-1.0     453\n",
       "dtype: int64"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Getting labels for a constant threshold of 1%. Will return 1 if the daily return is greater than 1%,\n",
    "# -1 if less than -1%, and  0 if in between.\n",
    "bars1 = fixed_time_horizon(close, 0.01, look_forward=1)\n",
    "bars1.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Frequency')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax1 = bars1.value_counts().reindex([-1, 0, 1]).plot(kind='bar', x='label', y='frequency')\n",
    "ax1.set_xlabel('Label')\n",
    "ax1.set_ylabel('Frequency')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Predictably, lowering the threshold results in fewer 0 labels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Frequency')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "bars2 = fixed_time_horizon(close, 0.001, look_forward=1)\n",
    "ax2 = bars2.value_counts().reindex([-1, 0, 1]).plot(kind='bar', x='label', y='frequency')\n",
    "ax2.set_xlabel('Label')\n",
    "ax2.set_ylabel('Frequency')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Labeling With Dynamic Threshold"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A major problem with the fixed time horizon method is the __seasonality__ of the data. Time bars in the middle of the trading day would look very different than those at the open or close. One way to get around this is to only use data which has been collected at the same time per day, such as close prices. Another method is to apply a dynamic threshold which can adjust for such differences. \n",
    "\n",
    "We will demonstrate two methods of setting a dynamic threshold:\n",
    "1. Using a rolling standard deviation\n",
    "2. Using SPY as the market return\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get rolling standard deviation\n",
    "msft_returns = close.pct_change(periods=1).shift(-1)\n",
    "rolling_std = msft_returns.rolling(10).std()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       " 0.0    1780\n",
       " 1.0     463\n",
       "-1.0     357\n",
       "dtype: int64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bars3 = fixed_time_horizon(close, rolling_std, look_forward=1)\n",
    "bars3.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Frequency')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEGCAYAAACUzrmNAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAASpklEQVR4nO3de7DndV3H8efL3RDJdFWOhLvYYm4qORq0EWVTJKVcyrUmC6dyQ3K7YGV2YbUm6GLhaJJ2MVehwEzFS7IFRYia0xSXAzgoorGDBMclOQZCBkqL7/74fY/+WM7u53cO53c5/J6PmTO/7+fyO9/3zJnd13y+11QVkiTtzyPGXYAkafIZFpKkJsNCktRkWEiSmgwLSVLT2nEXMAwHH3xwbdy4cdxlSNKqcvXVV3++qmYWG3tYhsXGjRuZnZ0ddxmStKok+c99jXkYSpLUZFhIkpoMC0lSk2EhSWoyLCRJTYaFJKnJsJAkNRkWkqQmw0KS1PSwvINb0vTYuP2icZcwNDefddK4S/gqVxaSpCbDQpLUZFhIkpoMC0lSk2EhSWoaWlgkOTfJ7Uk+0df3uiSfSnJdkr9Lsq5v7FVJdiX5dJLn9/Uf3/XtSrJ9WPVKkvZtmCuLvwaO36vvUuCZVfUs4D+AVwEkOQI4GfjW7jt/kWRNkjXAnwMnAEcAL+7mSpJGaGhhUVUfBe7Yq++fq2pP17wc2NBtbwHeVVVfrqrPALuAo7ufXVV1U1XdB7yrmytJGqFxnrN4KfCP3fZ64Na+sbmub1/9D5JkW5LZJLPz8/NDKFeSptdYwiLJbwF7gHcsdC0yrfbT/+DOqh1VtbmqNs/MLPq+cUnSMo38cR9JtgI/BBxXVQv/8c8Bh/VN2wDs7rb31S9JGpGRriySHA+cDrygqu7pG9oJnJzkkUkOBzYBVwJXAZuSHJ7kAHonwXeOsmZJ0hBXFkneCRwLHJxkDjiD3tVPjwQuTQJweVX9fFVdn+QC4JP0Dk+dVlX3d7/n5cAlwBrg3Kq6flg1S5IWN7SwqKoXL9J9zn7mvwZ4zSL9FwMXr2BpkqQl8g5uSVKTYSFJajIsJElNhoUkqcmwkCQ1GRaSpCbDQpLUNPLHfTwcbdx+0bhLGKqbzzpp3CVIGjNXFpKkJsNCktRkWEiSmgwLSVKTYSFJajIsJElNhoUkqcmwkCQ1GRaSpCbDQpLUZFhIkpoMC0lSk2EhSWoyLCRJTYaFJKnJsJAkNQ0tLJKcm+T2JJ/o63t8kkuT3Nh9Pq7rT5I3JdmV5LokR/V9Z2s3/8YkW4dVryRp34a5svhr4Pi9+rYDl1XVJuCyrg1wArCp+9kGvBl64QKcAXwncDRwxkLASJJGZ2hhUVUfBe7Yq3sLcF63fR7wwr7+86vncmBdkkOB5wOXVtUdVXUncCkPDiBJ0pCN+pzFIVV1G0D3+cSufz1wa9+8ua5vX/0PkmRbktkks/Pz8yteuCRNs0k5wZ1F+mo//Q/urNpRVZuravPMzMyKFidJ027UYfG57vAS3eftXf8ccFjfvA3A7v30S5JGaNRhsRNYuKJpK3BhX/9LuquijgHu6g5TXQI8L8njuhPbz+v6JEkjtHZYvzjJO4FjgYOTzNG7quks4IIkpwK3AC/qpl8MnAjsAu4BTgGoqjuS/D5wVTfv96pq75PmkqQhG1pYVNWL9zF03CJzCzhtH7/nXODcFSxNkrREk3KCW5I0wQwLSVKTYSFJajIsJElNhoUkqcmwkCQ1GRaSpCbDQpLUZFhIkpoMC0lSk2EhSWoyLCRJTYaFJKnJsJAkNRkWkqQmw0KS1GRYSJKaDAtJUpNhIUlqMiwkSU2GhSSpybCQJDUZFpKkJsNCktQ0lrBI8qtJrk/yiSTvTHJgksOTXJHkxiTvTnJAN/eRXXtXN75xHDVL0jQbeVgkWQ/8MrC5qp4JrAFOBl4LnF1Vm4A7gVO7r5wK3FlVTwXO7uZJkkZooLBI8swV3u9a4FFJ1gIHAbcBzwXe242fB7yw297StenGj0uSFa5HkrQfg64s/jLJlUl+Mcm6h7LDqvos8HrgFnohcRdwNfCFqtrTTZsD1nfb64Fbu+/u6eY/Ye/fm2Rbktkks/Pz8w+lREnSXgYKi6r6HuAngcOA2SR/m+QHl7PDJI+jt1o4HHgS8PXACYvtduEr+xnrr3FHVW2uqs0zMzPLKU2StA8Dn7OoqhuB3wZOB74PeFOSTyX50SXu8weAz1TVfFX9H/B+4LuBdd1hKYANwO5ue45eSNGNPxa4Y4n7lCQ9BIOes3hWkrOBG+idW/jhqnpGt332Evd5C3BMkoO6cw/HAZ8EPgz8WDdnK3Bht72za9ONf6iqHrSykCQNz9r2FAD+DHgr8Oqqunehs6p2J/ntpeywqq5I8l7gGmAPcC2wA7gIeFeSP+j6zum+cg7w9iS76K0oTl7K/iRJD92gYXEicG9V3Q+Q5BHAgVV1T1W9fak7raozgDP26r4JOHqRuV8CXrTUfUiSVs6g5yw+CDyqr31Q1ydJmgKDhsWBVfXFhUa3fdBwSpIkTZpBw+J/kxy10Ejy7cC9+5kvSXoYGfScxSuA9yRZuJz1UOAnhlOSJGnSDBQWVXVVkqcDT6N3k9ynunskJElTYNCVBcB3ABu77xyZhKo6fyhVSZImykBhkeTtwDcDHwPu77oLMCwkaQoMurLYDBzhndOSNJ0GvRrqE8A3DrMQSdLkGnRlcTDwySRXAl9e6KyqFwylKknSRBk0LM4cZhGSpMk26KWz/5Lkm4BNVfXBJAfRex2qJGkKDPqI8pfRe6XpW7qu9cAHhlWUJGmyDHqC+zTgOcDd8NUXIT1xWEVJkibLoGHx5aq6b6HRvbHOy2glaUoMGhb/kuTVwKO6d2+/B/j74ZUlSZokg4bFdmAe+Djwc8DF9N7HLUmaAoNeDfUVeq9Vfetwy5EkTaJBnw31GRY5R1FVT1nxiiRJE2cpz4ZacCC9d2I/fuXLkSRNooHOWVTVf/f9fLaq/gR47pBrkyRNiEEPQx3V13wEvZXGNwylIknSxBn0MNQf923vAW4GfnzFq5EkTaRBr4b6/mEXIkmaXIMehnrl/sar6g1L2WmSdcDbgGfSu8rqpcCngXfTe3XrzcCPV9WdSQK8ETgRuAf4maq6Zin7kyQ9NIPelLcZ+AV6DxBcD/w8cAS98xbLOXfxRuCfqurpwLOBG+jd+HdZVW0CLuvaACcAm7qfbcCbl7E/SdJDsJSXHx1VVf8DkORM4D1V9bNL3WGSxwDfC/wMQPfMqfuSbAGO7aadB3wEOB3YApzfvdL18iTrkhxaVbctdd+SpOUZdGXxZOC+vvZ99A4XLcdT6D065K+SXJvkbUm+HjhkIQC6z4Wn2q4Hbu37/lzX9wBJtiWZTTI7Pz+/zNIkSYsZNCzeDlyZ5MwkZwBXAOcvc59rgaOAN1fVkcD/8rVDTovJIn2L3U2+o6o2V9XmmZmZZZYmSVrMoDflvQY4BbgT+AJwSlX94TL3OQfMVdUVXfu99MLjc0kOBeg+b++bf1jf9zcAu5e5b0nSMgy6sgA4CLi7qt4IzCU5fDk7rKr/Am5N8rSu6zjgk8BOYGvXtxW4sNveCbwkPccAd3m+QpJGa9BLZ8+gd0XU04C/Ar4O+Bt6b89bjl8C3pHkAOAmequWRwAXJDkVuIXe86eg9zj0E4Fd9C6dPWWZ+5QkLdOgV0P9CHAkcA1AVe1OsuzHfVTVx3jgwwkXHLfI3KL3WldJ0pgMehjqvu4/7QLorl6SJE2JQcPigiRvAdYleRnwQXwRkiRNjUGfDfX67t3bd9M7b/E7VXXpUCuTJE2MZlgkWQNcUlU/ABgQkjSFmoehqup+4J4kjx1BPZKkCTTo1VBfAj6e5FJ6d1wDUFW/PJSqJEkTZdCwuKj7kSRNof2GRZInV9UtVXXeqAqSJE2e1jmLDyxsJHnfkGuRJE2oVlj0P/H1KcMsRJI0uVphUfvYliRNkdYJ7mcnuZveCuNR3TZdu6rqMUOtTpI0EfYbFlW1ZlSFSJIm11LeZyFJmlKGhSSpybCQJDUZFpKkJsNCktRkWEiSmgwLSVKTYSFJajIsJElNhoUkqcmwkCQ1jS0skqxJcm2Sf+jahye5IsmNSd6d5ICu/5Fde1c3vnFcNUvStBrnyuJXgBv62q8Fzq6qTcCdwKld/6nAnVX1VODsbp4kaYTGEhZJNgAnAW/r2gGeC7y3m3Ie8MJue0vXphs/rpsvSRqRca0s/gT4TeArXfsJwBeqak/XngPWd9vrgVsBuvG7uvkPkGRbktkks/Pz88OsXZKmzsjDIskPAbdX1dX93YtMrQHGvtZRtaOqNlfV5pmZmRWoVJK0oPWmvGF4DvCCJCcCBwKPobfSWJdkbbd62ADs7ubPAYcBc0nWAo8F7hh92ZI0vUa+sqiqV1XVhqraCJwMfKiqfhL4MPBj3bStwIXd9s6uTTf+oaryfeCSNEKTdJ/F6cArk+yid07inK7/HOAJXf8rge1jqk+SptY4DkN9VVV9BPhIt30TcPQic74EvGikhUmSHmCSVhaSpAllWEiSmgwLSVKTYSFJajIsJElNhoUkqcmwkCQ1GRaSpCbDQpLUZFhIkpoMC0lSk2EhSWoyLCRJTYaFJKnJsJAkNRkWkqQmw0KS1GRYSJKaDAtJUpNhIUlqMiwkSU1rx12ANG4bt1807hKG6uazThp3CXoYcGUhSWoyLCRJTSMPiySHJflwkhuSXJ/kV7r+xye5NMmN3efjuv4keVOSXUmuS3LUqGuWpGk3jpXFHuDXquoZwDHAaUmOALYDl1XVJuCyrg1wArCp+9kGvHn0JUvSdBt5WFTVbVV1Tbf9P8ANwHpgC3BeN+084IXd9hbg/Oq5HFiX5NARly1JU22s5yySbASOBK4ADqmq26AXKMATu2nrgVv7vjbX9e39u7YlmU0yOz8/P8yyJWnqjC0skjwaeB/wiqq6e39TF+mrB3VU7aiqzVW1eWZmZqXKlCQxprBI8nX0guIdVfX+rvtzC4eXus/bu/454LC+r28Ado+qVknSeK6GCnAOcENVvaFvaCewtdveClzY1/+S7qqoY4C7Fg5XSZJGYxx3cD8H+Gng40k+1vW9GjgLuCDJqcAtwIu6sYuBE4FdwD3AKaMtV5I08rCoqn9l8fMQAMctMr+A04ZalCRpv7yDW5LUZFhIkpoMC0lSk2EhSWoyLCRJTYaFJKnJsJAkNRkWkqQmw0KS1GRYSJKaDAtJUpNhIUlqMiwkSU2GhSSpybCQJDUZFpKkJsNCktRkWEiSmgwLSVKTYSFJajIsJElNhoUkqcmwkCQ1GRaSpKZVExZJjk/y6SS7kmwfdz2SNE1WRVgkWQP8OXACcATw4iRHjLcqSZoeqyIsgKOBXVV1U1XdB7wL2DLmmiRpaqwddwEDWg/c2teeA76zf0KSbcC2rvnFJJ8eUW3jcDDw+VHtLK8d1Z6mhn+/1evh/rf7pn0NrJawyCJ99YBG1Q5gx2jKGa8ks1W1edx1aHn8+61e0/y3Wy2HoeaAw/raG4DdY6pFkqbOagmLq4BNSQ5PcgBwMrBzzDVJ0tRYFYehqmpPkpcDlwBrgHOr6voxlzVOU3G47WHMv9/qNbV/u1RVe5YkaaqtlsNQkqQxMiwkSU2GhSSpaVWc4JZWqyRPp/e0gfX07g3aDeysqhvGWpi0RK4sVrEkjx53Ddq3JKfTezRNgCvpXQIe4J0+DHP1S3LKuGsYJa+GWsWS3FJVTx53HVpckv8AvrWq/m+v/gOA66tq03gq00qYtn9/HoaacEleua8hwJXFZPsK8CTgP/fqP7Qb04RLct2+hoBDRlnLuBkWk+8PgdcBexYZ8zDiZHsFcFmSG/nagzCfDDwVePnYqtJSHAI8H7hzr/4A/zb6csbHsJh81wAfqKqr9x5I8rNjqEcDqqp/SvIt9B6xv57efzBzwFVVdf9Yi9Og/gF4dFV9bO+BJB8ZfTnj4zmLCZfkacB/V9Xn+/q+sar+K8khVfW5MZYnaUoYFqtQkmuq6qhx1yFpenjMe3Va7P0ekjQ0hsXq9NZxFyBpungYSpLU5MpCktRkWEiSmgwL6SFI8sUlzD0zya8P6/dLw2RYSJKaDAtphSX54SRXJLk2yQeT9D9D6NlJPpTkxiQv6/vObyS5Ksl1SX53DGVL+2VYSCvvX4FjqupIeo8o/82+sWcBJwHfBfxOkicleR6wid5jQb4N+PYk3zvimqX98tlQ0srbALw7yaHAAcBn+sYurKp7gXuTfJheQHwP8Dzg2m7Oo+mFx0dHV7K0f4aFtPL+FHhDVe1McixwZt/Y3jc2Fb078v+oqt4ymvKkpfMwlLTyHgt8ttveutfYliQHJnkCcCy9t+ddArx04c2HSdYneeKoipUG4cpCemgOSjLX134DvZXEe5J8FrgcOLxv/ErgInrvtfj9qtoN7E7yDODfkwB8Efgp4Pbhly8Nxsd9SJKaPAwlSWoyLCRJTYaFJKnJsJAkNRkWkqQmw0KS1GRYSJKa/h9kxLDw8ZpuKQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "bars3 = fixed_time_horizon(close, 0.001, look_forward=1)\n",
    "ax3 = bars3.value_counts().reindex([-1, 0, 1]).plot(kind='bar', x='label', y='frequency')\n",
    "ax3.set_xlabel('Label')\n",
    "ax3.set_ylabel('Frequency')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Date\n",
       "2010-01-04    0.002602\n",
       "2010-01-05    0.000757\n",
       "2010-01-06    0.004213\n",
       "2010-01-07    0.003335\n",
       "2010-01-08    0.001394\n",
       "Name: Close, dtype: float64"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Threshold based on market returns\n",
    "spy = yf.Ticker('SPY')\n",
    "spy_df = spy.history(start='2010-1-1', end ='2020-5-18')\n",
    "market_close = spy_df['Close']\n",
    "\n",
    "market_returns = market_close.pct_change(1).shift(-1)\n",
    "market_returns.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Date\n",
       "2010-01-04    0.000000\n",
       "2010-01-05   -0.005778\n",
       "2010-01-06   -0.010378\n",
       "2010-01-07    0.006711\n",
       "2010-01-08   -0.012917\n",
       "                ...   \n",
       "2020-05-11   -0.022661\n",
       "2020-05-12   -0.015110\n",
       "2020-05-13    0.004351\n",
       "2020-05-14    0.014553\n",
       "2020-05-15         NaN\n",
       "Name: Close, Length: 2610, dtype: float64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "close.pct_change(periods=1).shift(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       " 1.0    1319\n",
       "-1.0     837\n",
       " 0.0     453\n",
       "dtype: int64"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bars4 = fixed_time_horizon(close, market_returns, look_forward=1)\n",
    "bars4.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Frequency')"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax4 = bars4.value_counts().reindex([-1, 0, 1]).plot(kind='bar', x='label', y='frequency')\n",
    "ax4.set_xlabel('Label')\n",
    "ax4.set_ylabel('Frequency')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Labeling with Standardization "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scaling each return by the mean and standard deviation is also a potential solution in getting around the non-homogeneaity of the data, as it could adjust for volatility differences between different bars. If standardization is desires, a rolling window must be given."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       " 0.0    1787\n",
       " 1.0     415\n",
       "-1.0     403\n",
       "dtype: int64"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bars5 = fixed_time_horizon(close, 1, look_forward=1, standardized=True, window=5)\n",
    "bars5.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Frequency')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax5 = bars5.value_counts().reindex([-1, 0, 1]).plot(kind='bar', x='label', y='frequency')\n",
    "ax5.set_xlabel('Label')\n",
    "ax5.set_ylabel('Frequency')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Error Handling"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Warnings will be raised if look_forward or window is greater than the length of the data. In this case, the function will still run, but all labels will be NaN. An error is raised if standardized is set to True but the window is not specified correctly (as an int)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\ruifan\\mlfinlab\\mlfinlab\\labeling\\fixed_time_horizon.py:45: UserWarning: look_forward period is greater than the length of the Series. All labels will be NaN.\n",
      "  UserWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Date\n",
       "2010-01-04   NaN\n",
       "2010-01-05   NaN\n",
       "2010-01-06   NaN\n",
       "2010-01-07   NaN\n",
       "2010-01-08   NaN\n",
       "              ..\n",
       "2020-05-11   NaN\n",
       "2020-05-12   NaN\n",
       "2020-05-13   NaN\n",
       "2020-05-14   NaN\n",
       "2020-05-15   NaN\n",
       "Length: 2610, dtype: float64"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fixed_time_horizon(close, 0.01, look_forward=99999999)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\ruifan\\mlfinlab\\mlfinlab\\labeling\\fixed_time_horizon.py:53: UserWarning: window is greater than the length of the Series. All labels will be NaN.\n",
      "  warnings.warn('window is greater than the length of the Series. All labels will be NaN.', UserWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Date\n",
       "2010-01-04   NaN\n",
       "2010-01-05   NaN\n",
       "2010-01-06   NaN\n",
       "2010-01-07   NaN\n",
       "2010-01-08   NaN\n",
       "              ..\n",
       "2020-05-11   NaN\n",
       "2020-05-12   NaN\n",
       "2020-05-13   NaN\n",
       "2020-05-14   NaN\n",
       "2020-05-15   NaN\n",
       "Length: 2610, dtype: float64"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fixed_time_horizon(close, 0.01, look_forward=1, standardized=True, window=99999999)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "ename": "AssertionError",
     "evalue": "when standardized is True, window must be int",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-18-857b58450c0d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mfixed_time_horizon\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mclose\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0.01\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlook_forward\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstandardized\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32mc:\\users\\ruifan\\mlfinlab\\mlfinlab\\labeling\\fixed_time_horizon.py\u001b[0m in \u001b[0;36mfixed_time_horizon\u001b[1;34m(close, threshold, look_forward, standardized, window)\u001b[0m\n\u001b[0;32m     49\u001b[0m     \u001b[1;32mif\u001b[0m \u001b[0mstandardized\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     50\u001b[0m         \u001b[1;31m# Error handling\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 51\u001b[1;33m         \u001b[1;32massert\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwindow\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mint\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"when standardized is True, window must be int\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     52\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mwindow\u001b[0m \u001b[1;33m>=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mforward_return\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     53\u001b[0m             \u001b[0mwarnings\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'window is greater than the length of the Series. All labels will be NaN.'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mUserWarning\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAssertionError\u001b[0m: when standardized is True, window must be int"
     ]
    }
   ],
   "source": [
    "fixed_time_horizon(close, 0.01, look_forward=1, standardized=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## Conclusion"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook presents the fixed horizon method, a simple method of labeling data for later use in machine learning algorithms. In this process:\n",
    " - Forward rates of return for assets are calculated based on tick data, usually in the form of time bars.\n",
    " - The forward return rate is compared to a threshold for the return. The threshold can be a constant, or a dynamic series corresponding to every timestamp in the data.\n",
    " - Each observation is compared to the threshold, and is labeled -1 if it is below -threshold, 0 if it is between -threshold and +threshold, and 1 if it is greater than +threshold.\n",
    "\n",
    "In Dixon's paper, the data is labelled using this method. Subsequently a neural network is trained to to predict the label based on the data. A simple trading strategy in which a long position is taken if a ticker is classified as 1, and short if it's classified at -1, can then be applied."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## References"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. Dixon, M., Klabjan, D. and Jin Hoon, B., 2020. Classification-based Financial Markets Prediction using Deep Neural Networks. arXiv, [online] Available at: https://arxiv.org/abs/1603.08604\n",
    "\n",
    "2. López de Prado, M., 2018. Advances In Financial Machine Learning. pp.43-44.\n",
    "\n",
    "3. López de Prado, M., 2020. Machine Learning For Asset Managers. pp.65-66.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
